import { NativeHelper } from "../../native/NativeHelper";
import { IADAble, ADConfig, AdFrom, ADType, ADEvent } from "../IADAble";

export class NativeAd extends IADAble{
    protected _className:string = "sdk.{0}.Ad";
    
    init(type: string, config:ADConfig): IADAble {
        this._className = this._className.replace("{0}", type);
        return super.init(type, config);
    }

    loadBanner(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex:number=0): void {
        let fail = ()=>{
            if(++unitIdIndex < this._config.bannerUnitIds.length){
                this.loadBanner(from, caller, onSuccess, onFail, unitIdIndex);
            }else if(caller && onFail != null){
                onFail && onFail.apply(caller);
            }
        }
        let unitId = this._config.bannerUnitIds[unitIdIndex];
        this._loadBanner(unitId, caller, onSuccess, fail)
    }

    protected _loadBanner(unitId:string, caller?: any, onSuccess?: Function, fail?: Function){
        let callbacks:string[] = [];
        callbacks.push(onSuccess != null ? NativeHelper.registerCallbackOnce(caller, onSuccess) : "");
        callbacks.push(NativeHelper.registerCallbackOnce(this, fail));
        NativeHelper.call(this._className, "loadBanner", unitId, ...callbacks);
    }

    showBanner(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex:number=0): void {
        let fail = ()=>{
            if(++unitIdIndex < this._config.bannerUnitIds.length){
                this.showBanner(from, caller, onSuccess, onFail, unitIdIndex);
            }else if(caller && onFail != null){
                onFail && onFail.apply(caller);
            }
        }
        let unitId = this._config.bannerUnitIds[unitIdIndex];
        this._showBanner(unitId, caller, onSuccess, fail);
    }

    protected _showBanner(unitId:string, caller?: any, onSuccess?: Function, fail?: Function){
        let callbacks:string[] = [];
        callbacks.push(onSuccess != null ? NativeHelper.registerCallbackOnce(caller, onSuccess) : "");
        callbacks.push(NativeHelper.registerCallbackOnce(this, fail));
        NativeHelper.call(this._className, "showBanner", unitId, ...callbacks);
    }

    hideBanner(): void {
        NativeHelper.call(this._className, "hideBanner");
    }

    /**
     * 显示激励视频，失败后根据config尝试其他广告位。
     * @param caller 
     * @param onSuccess 
     * @param onFail 
     * @param unitIdIndex 
     * @param report 
     */
    showRewardVideo(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex:number=0): void {
        let fail = ()=>{
            if(caller && onFail != null){
                from && this._report(ADType.REWARD_VIDEO, ADEvent.SHOW_FAIL, from, "");
                onFail && onFail.apply(caller);
            }
        }
        let success = ()=>{
            from && this._report(ADType.REWARD_VIDEO, ADEvent.SHOW_COMPLETE, from, "");
            onSuccess && onSuccess.apply(caller)
        }
        let unitId = this._config.rewardVideoUnitIds[unitIdIndex];
        from && this._report(ADType.REWARD_VIDEO, ADEvent.SHOW, from, "");
        this._showRewardVideo(unitId, caller, success, fail);
    }

    protected _showRewardVideo(unitId:string, caller?: any, onSuccess?: Function, fail?: Function){
        let callbacks:string[] = [];
        callbacks.push(onSuccess != null ? NativeHelper.registerCallbackOnce(caller, onSuccess) : "");
        callbacks.push(NativeHelper.registerCallbackOnce(this, fail));
        NativeHelper.call(this._className, "showRewardVideo", unitId, ...callbacks);
    }

    loadInterstitial(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex:number=0): void {
        let fail = ()=>{
            if(++unitIdIndex < this._config.interstitialUnitIds.length){
                this.loadInterstitial(from, caller, onSuccess, onFail, unitIdIndex);
            }else if(caller && onFail != null){
                onFail && onFail.apply(caller);
            }
        }
        let unitId = this._config.interstitialUnitIds[unitIdIndex];
        this._loadInterstitial(unitId, caller, onSuccess, fail);
    }

    protected _loadInterstitial(unitId:string, caller?: any, onSuccess?: Function, fail?: Function){
        let callbacks:string[] = [];
        callbacks.push(onSuccess != null ? NativeHelper.registerCallbackOnce(caller, onSuccess) : "");
        callbacks.push(NativeHelper.registerCallbackOnce(this, fail));
        NativeHelper.call(this._className, "loadInterstitial", unitId, ...callbacks);
    }

    showInterstitial(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex:number=0): void {
        let fail = ()=>{
            if(++unitIdIndex < this._config.interstitialUnitIds.length){
                this.showInterstitial(from, caller, onSuccess, onFail, unitIdIndex);
            }else if(caller && onFail != null){
                onFail && onFail.apply(caller);
            }
        }
        let unitId = this._config.interstitialUnitIds[unitIdIndex];
        this._showInterstitial(unitId, caller, onSuccess, fail);
    }

    protected _showInterstitial(unitId:string, caller?: any, onSuccess?: Function, fail?: Function){
        let callbacks:string[] = [];
        callbacks.push(onSuccess != null ? NativeHelper.registerCallbackOnce(caller, onSuccess) : "");
        callbacks.push(NativeHelper.registerCallbackOnce(this, fail));
        NativeHelper.call(this._className, "showInterstitial", unitId, ...callbacks);
    }

}